home *** CD-ROM | disk | FTP | other *** search
- #include "ufk.h"
- #include <pwd.h>
- #include <sgtty.h>
- #include <signal.h>
- #include <setjmp.h>
- #include <stat.h>
-
- /*
- * split command line into seperate strings
- */
-
- split(cmd_str)
- char *cmd_str;
- {
- char *malloc();
- char pass,
- *p,
- *q,
- result[128];
-
- numprm = 0; /* no parameters yet */
- for (pass = 0; pass < 2; pass++) /* find # of params in pass 1 */
- { /* alloc pointer array and store */
- if (pass > 0) /* pointers in pass 2 */
- {
- if ((params = malloc(numprm * sizeof(char *))) == NULL)
- { /* allocate space for pointer array to parameters */
- prterr(ER_NOMEM);
- kerm_exit();
- }
- numprm = 0; /* restart scan */
- }
- p = cmd_str; /* setup pointer to input string */
- while (*p && (*p != COMMENT)) /* do till end of string */
- {
- while (isspace(*p)) /* strip leading white space */
- p++;
- if (pass > 0)
- {
- sscanf(p, "%s", result); /* get part of input string */
- if ((q = malloc(strlen(result) + 1)) == NULL) /* get str space */
- {
- prterr(ER_NOMEM);
- kerm_exit();
- }
- strcpy(q, result); /* copy part to allocated memory */
- params[numprm] = q; /* save pointer to string */
- }
- numprm++; /* one more */
- while ((!isspace(*p)) && *p) /* skip to end of this string */
- p++;
- }
- }
- return (TRUE);
- }
-
- /*
- * parse command components
- */
-
- parse(command_string, table)
- char *command_string;
- TABLE table[];
- {
- char i = 0,
- j;
- int mstat,
- cmd_num = 0,
- tv = 0,
- unique = FALSE;
-
- make_lower(command_string); /* convert to lower case */
- while (*table[i].string) /* do until end of command table */
- {
- mstat = match(table[i].string, command_string); /* do compare */
- if (mstat == -1)
- return (table[i].funcadr); /* exact match found */
- if (mstat != 0) /* some characters did match */
- {
- if (mstat > tv) /* longer than so far ? */
- {
- tv = mstat; /* save longest length */
- cmd_num = i; /* remember which command */
- unique = TRUE; /* it's unique so far */
- }
- j = i;
- while (*table[++j].string) /* start new search from next entry */
- {
- mstat = match(table[j].string, command_string); /* other match ? */
- if (mstat == -1)
- return (table[j].funcadr); /* exact match */
- if (mstat != 0) /* some characters did match */
- {
- if (mstat > tv) /* longer than so far ? */
- {
- tv = mstat; /* save greatest length */
- cmd_num = i; /* remember which command */
- unique = TRUE; /* it's unique so far */
- }
- if (mstat == tv) /* another one of the same length ? */
- unique = FALSE; /* yes, it's not unique anymore */
- }
- }
- if (!unique) /* if it was'nt unique it's ambiguous */
- return (NULL);
- else
- return (table[cmd_num].funcadr); /* else it's a valid command */
- }
- i++; /* try next entry */
- }
- if (cmd_num == 0)
- return (ERROR); /* no such command */
- else return (table[cmd_num].funcadr); /* return command number */
- }
-
- match(s, t)
- char *s, *t;
- {
- int len = 0,
- inputlen;
-
- inputlen = strlen(t); /* length of input command */
- while (*s) /* do until end of string */
- {
- if (*s++ != *t++) /* if no match */
- {
- if (inputlen == 0) /* total command checked */
- return (len); /* return matched length */
- else
- return (0); /* no match for this command */
- }
- len++; /* one more character done */
- --inputlen; /* count down input string length */
- }
- return (-1); /* full match found */
- }
-
- /*
- * m a k e _ u p p e r
- *
- * Convert string to upper case
- */
-
- make_upper(p)
- char *p;
- {
- while (*p)
- {
- if (islower(*p))
- *p = toupper(*p);
- p++;
- }
- }
-
- /*
- * m a k e _ l o w e r
- *
- * Convert string to lower case
- */
-
- make_lower(p)
- char *p;
- {
- while (*p)
- {
- if (isupper(*p))
- *p = tolower(*p);
- p++;
- }
- }
-
- /*
- * p r e r r p k t
- *
- * Print contents of error packet received from remote host.
- */
- prerrpkt(msg)
- char *msg;
- {
- if (!nooutput)
- {
- disp(0,19,"Kermit aborting with following error from remote host:");
- foreground();
- disp(0,20,msg);
- background();
- beep();
- }
- }
-
- /*
- * send ASCII file to remote without protocol.
- * handshake is used.
- */
-
- jmp_buf trn_env;
-
- trnsmit()
- {
- FILE *xmitfp;
- char c1;
- int c, trnsm_int();
- struct sgttyb mode;
-
- if (numprm <= 1) /* check for parameters */
- prterr(ER_FSPCREQ);
- else
- {
- if ((xmitfp = fopen(params[1], "r")) == NULL)
- prterr(ER_OPENERR);
- else
- {
- if (!open_port(FALSE,FALSE))
- prterr(ER_POPNERR);
- else
- {
- signal(SIGINT,trnsm_int);
- if (!setjmp(trn_env))
- while ((c = getc(xmitfp)) != EOF) /* get character from file */
- {
- if (debug)
- putc(c, stdout); /* send to console as well */
- gtty(ttyfd,&mode);
- if (mode.sg_speed & INCHR)
- {
- read(ttyfd,&c1,1); /* Check received character */
- if ((c1 & 0177) == dstop && dstop != 0)/* Stop chr ? */
- do /* Yes */
- read(ttyfd,&c1,1); /* Wait for next character */
- while ((c1 & 0177) != dstart);/* Wait for start chr */
- }
- c1 = c; /* Only high byte of int would be send (=0) */
- write(ttyfd,&c1,1); /* Send to output port */
- }
- else
- if (debug)
- fputs("\n",stdout);
- fclose(xmitfp);
- kdelay(1); /* Give the port time to finish */
- close_port(FALSE,FALSE);
- }
- }
- }
- }
-
- trnsm_int()
- {
- longjmp(trn_env,TRUE); /* Transmit interrupted... */
- }
-
-
- /*
- * Read KERMIT commands from file
- */
-
- take(fspec,echo)
- char *fspec, echo;
- {
- FILE *tfp;
- char data[133], /* Command input */
- fname[80];
-
- if (fspec == NULL)
- {
- if (numprm > 1)
- strcpy(fname, params[1]);
- else
- return(prterr(ER_FSPCREQ));
- }
- else
- strcpy(fname,fspec);
-
- if ((tfp = fopen(fname,"r")) != NULL) /* Look for command file */
- { /* Found file, read commands */
- while (fgets(data,132,tfp))
- {
- if (echo)
- {
- fputs(prompt,stdout); /* Echo prompt */
- fputs(data,stdout); /* Echo command */
- }
- data[strlen(data) - 1] = '\0'; /* Zap newline */
- if (data[0] && data[0] != COMMENT) /* Not a blank line */
- kerm_command(data); /* Do command */
- }
- fclose(tfp);
- }
- else
- {
- if (fspec == NULL)
- return(prterr(ER_OPENERR));
- else
- return(ER_OPENERR);
- }
- return(NULL);
- }
-
- /*
- * call UniFLEX to perform external command
- */
-
- do_uniflex()
- {
- static char *shell = { "/bin/shell" };
- static char *opt = { "+xc" };
- char *prm[4],
- *p,
- cmdline[256];
- int i,
- kerm_exit();
-
- prm[0] = &shell[5]; /* setup program name */
- prm[1] = prm[3] = 0; /* end of parameters pointer */
- if (numprm > 1)
- {
- prm[1] = opt; /* one shot option */
- prm[2] = p = cmdline; /* pointers to start of commandline */
- for (i = 1; i < numprm; i++)
- {
- strcpy(p,params[i]); /* copy params into one line */
- p += strlen(p); /* point after command */
- *p++ = ' '; /* separator */
- }
- *p = '\0'; /* end of string */
- }
- if (!fork()) /* duplicate myself */
- {
- execvp(shell,prm); /* execute command in child */
- prterr(ER_SPAWN); /* should not come here */
- }
- else
- {
- signal(SIGTERM,SIG_IGN); /* Ignore this signals */
- signal(SIGHUP,SIG_IGN);
- signal(SIGQUIT,SIG_IGN);
- signal(SIGINT,SIG_IGN);
- wait(0); /* wait for child to die */
- signal(SIGTERM,kerm_exit); /* Set signals again */
- signal(SIGHUP,kerm_exit);
- signal(SIGQUIT,SIG_DFL); /* Make these default */
- signal(SIGINT,SIG_DFL);
- }
- }
-
- disk_free()
- {
- char dev[30];
- long size;
-
- if (numprm <= 1)
- strcpy(dev,"."); /* use current place if not specified */
- else
- strcpy(dev,params[1]); /* use specified place */
- if ((size = get_free(dev)) != -1l)/* if no error... */
- printf("Number of free blocks: %ld (%ld bytes)\n",size, size * 512);
- }
-
-
- chd()
- {
- struct passwd *p;
-
- if (numprm <= 1)
- {
- if ((p = getpwuid(getuid())) == NULL)
- prterr(ER_GETPWDID);
- chdir(p->pw_dir);
- set_dir(p->pw_dir);
- }
- else
- {
- if (chdir(params[1]) == ERROR)
- prterr(ER_INVDIR);
- else
- set_dir(params[1]);
- }
- }
-
-
- /*
- * show statistics about connection
- */
-
- statistics()
- {
- static char s1[] = "Characters sent:\t\t%ld\n";
- static char s2[] = "Data characters sent:\t\t%ld\n";
- static char s3[] = "NAK's sent:\t\t\t%d\n";
- static char s4[] = "Packets sent:\t\t\t%d\n";
- static char s5[] = "Characters received:\t\t%ld\n";
- static char s6[] = "Data characters received:\t%ld\n";
- static char s7[] = "NAK's received:\t\t\t%d\n";
- static char s8[] = "Packets received:\t\t%d\n";
-
- printf("Totals for the last transfer:\n\n");
- printf(s1, chr_sent);
- printf(s2, dchr_sent);
- printf(s3, nak_sent);
- printf(s4, pack_sent);
- printf(s5, chr_rec);
- printf(s6, dchr_rec);
- printf(s7, nak_rec);
- printf(s8, pack_rec);
- printf("Effective data rate:\t\t%d baud\n", data_rate);
- printf("\nTotals since KERMIT was started:\n\n");
- printf(s1, t_chr_sent);
- printf(s2, t_dchr_sent);
- printf(s3, t_nak_sent);
- printf(s4, t_pack_sent);
- printf(s5, t_chr_rec);
- printf(s6, t_dchr_rec);
- printf(s7, t_nak_rec);
- printf(s8, t_pack_rec);
- printf("Mean effective data rate:\t%d baud\n", t_data_rate);
- }
-
- #define POLYIT 0x8408 /* Polynomial for CRC-CCITT */
- #define POLY16 0xa001 /* Polynomial for CRC-16 (not used here) */
-
- unsigned int crc_value, crc[256]; /* Global accessible variables */
-
- init_crc_table()
- {
- int count, nr;
- unsigned int accum, crcch;
-
- for (count = 0; count < 256; count++) /* Build CRC lookup table */
- {
- accum = 0;
- crcch = count;
- for (nr = 0; nr < 8; nr++)
- {
- if (((accum & 0xff) ^ crcch) & 1)
- accum = (accum / 2) ^ POLYIT;
- else
- accum = (accum / 2);
- crcch = (crcch / 2);
- }
- crc[count] = accum; /* Save calculated value in table */
- }
- }
-
- zero_crc()
- {
- crc_value = 0; /* Initial value is zero */
- }
-
- unsigned int calc_crc(value)
- unsigned char value;
- {
- crc_value = crc[value ^ (crc_value & 0xff)] ^ ((crc_value >> 8) & 0xff);
- return crc_value; /* Return accumulated value so far */
- }
-
- beep()
- {
- if (!remote && !nooutput)
- putc(BELL,stdout);
- }
-
- disp(x,y,string)
- int x,y;
- char *string;
- {
- if (!remote)
- {
- posit(x,y);
- fputs(string,stdout);
- if (!screen && !nooutput)
- fputs("\n",stdout);
- }
- }
-
- set_frame()
- {
- if (screen && !remote && !nooutput)
- {
- clear_screen();
- posit(28,0);
- foreground();
- fprintf(stdout," KERMIT version %s ",VERSION);
- background();
- if (sflg || rflg)
- {
- disp(0,4,"Transferred:");
- disp(27,4,"Percentage:");
- }
- disp(0,6,"Packet received:");
- disp(0,7,"Packet transmitted:");
- if (debug >= 1)
- {
- disp(0,9,"Data received:");
- disp(0,11,"Data transmitted:");
- disp(0,13,"Receive state:");
- disp(36,13,"Send state:");
- disp(27,6,"Type:");
- disp(27,7,"Type:");
- disp(37,6,"Length:");
- disp(37,7,"Length:");
- disp(50,6,"Checksum:");
- disp(50,7,"Checksum:");
- }
- curs_off(); /* Turn off cursor */
- }
- }
-
- disp_state(x,y,state)
- int x,y;
- char state;
- {
- static char sa[] = "Attribute ";
- static char sb[] = "Break ";
- static char sc[] = "Complete ";
- static char sd[] = "Data ";
- static char sf[] = "Filename ";
- static char sq[] = "Abort ";
- static char sr[] = "Receive init";
- static char ss[] = "Send init ";
- static char st[] = "Timeout ";
- static char sz[] = "End of file ";
- static char un[] = "Unknown ";
- char dsc[5];
-
- if (debug == 2)
- strcpy(dsc,"%s\r");
- else
- strcpy(dsc,"%s\r\l");
- posit(x,y);
- switch(state)
- {
- case 'A':
- prtdbg(dsc,sa);
- break;
- case 'B':
- prtdbg(dsc,sb);
- break;
- case 'C':
- prtdbg(dsc,sc);
- break;
- case 'D':
- prtdbg(dsc,sd);
- break;
- case 'F':
- prtdbg(dsc,sf);
- break;
- case 'Q':
- prtdbg(dsc,sq);
- break;
- case 'R':
- prtdbg(dsc,sr);
- break;
- case 'S':
- prtdbg(dsc,ss);
- break;
- case 'T':
- prtdbg(dsc,st);
- break;
- case 'Z':
- prtdbg(dsc,sz);
- break;
- default:
- prtdbg(dsc,un);
- }
- }
-
- prtdbg(fmt, a1, a2, a3, a4, a5, a6)
- char *fmt;
- {
- if ((debug >= 1) && !remote)
- fprintf(stdout,fmt,a1,a2,a3,a4,a5,a6);
- if (debug == 2)
- fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
- }
-
- prtdbgf(fmt, a1, a2, a3, a4, a5, a6)
- char *fmt;
- {
- if (debug == 2)
- fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
- }
-
- map_case(name,mode)
- char *name;
- int mode;
- {
- if (mapping)
- {
- if (mode == IN)
- make_lower(name);
- else if (mode == OUT)
- make_upper(name);
- }
- }
-
- new_name(s)
- char *s;
- {
- struct stat buf;
- int num;
- char new_str[15],
- num_str[5];
-
- num = 0;
- do /* Construct new filename */
- { /* until new name not found */
- if (num++ > 4095) /* Bump counter */
- {
- error(PER_CREATE,"%s",new_str);/* FATAL error */
- kerm_exit(); /* More than 4096 files ??? */
- }
- strncpy(new_str,s,10); /* Copy 10 characters at most */
- new_str[10] = '\0'; /* Truncate at position 10 */
- sprintf(num_str,".%03x",num); /* Format new filename */
- strcat(new_str,num_str);
- }
- while (!stat(new_str,&buf)); /* If it exists, try again */
- strcpy(s,new_str); /* Save new filename */
- }
-
- synerr(threshold)
- int threshold;
- {
- if ((threshold != 0) && (numprm >= threshold))
- return FALSE;
- prterr(ER_SYNERR);
- return TRUE;
- }
-
- check_bg()
- {
- int oldsig;
-
- oldsig = signal(SIGINT,SIG_IGN); /* Get old KBD signal */
- signal(SIGINT,oldsig); /* Restore */
- return oldsig; /* TRUE if we're in the background */
- }
-